﻿using Ninject;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using WaitLess.App.Services;
using WaitLess.App.Services.Interfaces;
using WaitLess.Business.Model;
using WaitLess.Business.Services.Interfaces;

namespace WaitLess.App.ViewModels
{
    public class MainViewModel : ViewModelBase
    {
        private readonly IDataCache _dataCache;
        private readonly INavigationService _navigationService;

        private delegate void ShowMunicipalOffice(MunicipalOffice office);

        private MunicipalOfficeViewModel _selectedMunicipalOffice;
        public MunicipalOfficeViewModel SelectedMunicipalOffice
        {
            get { return _selectedMunicipalOffice; }
            set { SetProperty(ref _selectedMunicipalOffice, value, "SelectedMunicipalOffice"); }
        }

        public ObservableCollection<MunicipalOfficeViewModel> Districtshuizen { get; private set; }
        public ObservableCollection<MunicipalOfficeViewModel> Stadskantoren { get; private set; }

        public MainViewModel(IDataCache dataCache, INavigationService navigationService)
        {
            if (dataCache == null) throw new ArgumentNullException("dataCache");
            if (navigationService == null) throw new ArgumentNullException("navigationService");

            _navigationService = navigationService;
            _dataCache = dataCache;

            Districtshuizen = new ObservableCollection<MunicipalOfficeViewModel>();
            Stadskantoren = new ObservableCollection<MunicipalOfficeViewModel>();

            PropertyChanged += SelectedMunicipalOffice_PropertyChanged;
        }

        private void SelectedMunicipalOffice_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "SelectedMunicipalOffice")
                if (CanOpenMunicipalOffice())
                    OpenMunicipalOffice();
        }

        #region LoadData

        public override void LoadData()
        {
            SelectedMunicipalOffice = null;

            if (IsDataLoaded)
                return;

            _dataCache.Load(LoadMunicipalOffices);
        }

        private void LoadMunicipalOffices()
        {
            ShowDistrictshuizen(_dataCache.Districshuizen);
            ShowStadskantoren(_dataCache.Stadskantoren);

            UpdateUI(() => IsDataLoaded = true);
        }

        private void ShowDistrictshuizen(IEnumerable<MunicipalOffice> districtshuizen)
        {
            ShowMunicipalOffice showDistrictshuis = delegate(MunicipalOffice o) 
            { 
                Districtshuizen.Add(new MunicipalOfficeViewModel 
                { 
                    Id = o.Id, Title = o.Name, District = o.District, Latitude = o.Latitude, Longitude = o.Longitude
                }); 
            };

            foreach (var districtshuis in districtshuizen)
            {
                UpdateUI(showDistrictshuis, districtshuis);
            }
        }

        private void ShowStadskantoren(IEnumerable<MunicipalOffice> stadskantoren)
        {
            ShowMunicipalOffice showStadskantoor = delegate(MunicipalOffice o) 
            { 
                Stadskantoren.Add(new MunicipalOfficeViewModel 
                { 
                    Id = o.Id, Title = o.Name, District = o.District, Latitude = o.Latitude, Longitude = o.Longitude
                }); 
            };

            foreach (var stadskantoor in stadskantoren)
            {
                UpdateUI(showStadskantoor, stadskantoor);
            }
        }

        #endregion

        #region OpenMunicipalOffice

        private bool CanOpenMunicipalOffice()
        {
            return (SelectedMunicipalOffice != null);
        }

        private void OpenMunicipalOffice()
        {
            _navigationService.NavigateToDetailsPage(SelectedMunicipalOffice.Id);
        }

        #endregion
    }
}